package com.cius.ssm.controller;

import com.cius.ssm.controller.validation.ValidGroup1;
import com.cius.ssm.controller.validation.ValidGroup2;
import com.cius.ssm.entity.Product;
import com.cius.ssm.entity.ProductAndUser;
import com.cius.ssm.entity.ProductAndUserVo;
import com.cius.ssm.exception.CustomException;
import com.cius.ssm.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by ciuscheung on 17/4/4.
 */
@Controller
//窄化请求映射,设置url访问根目录,便于管理各个controller中的url
//url=根目录+子目录,在这里最终访问的即为:"/product/findProduct.action"
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductService productService;

//    商品分类
//    productTypes1 表示最终将方法返回值放在request中的key
    @ModelAttribute("productTypes1")
    public Map<String,String> getProductTypes(){
        Map<String,String> productTypes = new HashMap<String,String>();
        productTypes.put("101","数码");
        productTypes.put("102","图书");
        return productTypes;
    }

    //返回ModelAndView类型
    //value为url的子目录
    //method为限制http访问请求的方法,可以指定一个或多个,是一个枚举类型
    @RequestMapping(value = "/findProductByName",method = {RequestMethod.GET,RequestMethod.POST})
    public ModelAndView findProductByName(HttpServletRequest request,ProductAndUserVo productAndUserVo) throws Exception{
//      测试forward和redirect后request是否共享
        String id = request.getParameter("id");
        System.out.println(id);
//        ProductAndUserVo productAndUserVo = new ProductAndUserVo();
//        ProductAndUser product = new ProductAndUser();
//        product.setName("");
//        productAndUserVo.setProductAndUser(product);

        //异常处理
        List<ProductAndUser> lists = productService.findProductAndUser(productAndUserVo);
        if (lists.size() == 0){
            throw new CustomException("商品信息不存在");
        }
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("lists",lists);
        modelAndView.setViewName("product/productList");
        return modelAndView;
    }

    //返回String类型,返回所有商品信息
    @RequestMapping(value = "/findAllProducts",method = {RequestMethod.GET})
    public String findAllProducts(Model model) throws Exception{
        ProductAndUserVo productAndUserVo = new ProductAndUserVo();
        ProductAndUser product = new ProductAndUser();
        product.setName("");
        productAndUserVo.setProductAndUser(product);
        List<ProductAndUser> lists = productService.findProductAndUser(productAndUserVo);
//        通过形参中的model将model数据传到页面
//        相当于modelAndView.addObject方法
        model.addAttribute("lists",lists);
        return "product/productList";
    }

    //商品编辑页面
    @RequestMapping(value = "/findProductById")
//    @RequestParam里边指定request传入参数的名称和形参绑定
//    required属性指定参数是否必须输入
//    defaultValue可以设置默认值,如果id没有输入,可以将默认值与形参绑定
    public String findProductById(Model model,@RequestParam(value = "id",required = true,defaultValue = "1") int id111)throws Exception{
        Product product = productService.findProductById(id111);

        //异常处理
        //判断是否为空,根据id没有查到商品,抛出异常,提示用户商品信息不存在
//        if (product == null){
//            throw new CustomException("修改的商品信息不存在");
//        }
        model.addAttribute("productAndUser",product);
        return "product/productEdit";
    }

    //RESTful风格url测试
    @RequestMapping("/findProductByIdRESTful/{id}")
    //@RequestMapping将请求的商品信息的json串转成ProductAndUser对象
    //@ResponseBody将productAndUser转换成json格式输出
    //findProductByIdRESTful/{id}: {xxx}占位符,请求url可以是"findProductByIdRESTful/1"或"findProductByIdRESTful/2"
    //通过在方法中@PathVariable获取{xxx}中xxx的变量
    @ResponseBody
    public Product findProductByIdRESTful(@PathVariable("id") int id1)throws Exception{
        //方法使用@PathVariable获取id值,使用model传回到页面
        Product product = productService.findProductById(id1);
        return product;
    }

    //redirect和forward
    @RequestMapping(value = "/findProductById1")
    public String findProductById1()throws Exception{
//        重定向到商品信息列表
//        return "redirect:findProduct.action";
//        页面转发
        return "forward:findProduct.action";
    }

//    POJO的绑定,商品信息提交
//    在需要校验的pojo前边加上@Validated,后边加上BindingResult bindingResult接收校验出错信息
//    注意: @Validated 和 BindingResult bindingResult 是配对出现的,并且形参顺序是固定的(一前一后)
//    @Validated(value = {ValidGroup1.class})指定使用ValidGroup1分组的校验
//    @ModelAttribute("productAndUser")可以指定pojo回显到页面在request中的key(可以不与pojo类型一致)
    @RequestMapping(value = "/editSubmit")
    public String editSubmit(
            Model model,
            HttpServletRequest request,
            @ModelAttribute("productAndUser") @Validated(value = {ValidGroup1.class, ValidGroup2.class}) ProductAndUser productAndUser,
            BindingResult bindingResult,
            //接收商品上传图片
            MultipartFile product_pic
            )throws Exception{

//        获取校验错误信息
        if(bindingResult.hasErrors()){
            //输出错误信息
            List<ObjectError> errors = bindingResult.getAllErrors();
            for (ObjectError objectError:errors) {
                //输出错误信息
                System.out.println(objectError.getDefaultMessage());
            }
//            将错误信息传到页面
            model.addAttribute("errors",errors);

//            可以直接使用model.addAttribute方法将提交的pojo回显到页面
            model.addAttribute("productAndUser",productAndUser);
//            出错重新返回到商品修改页面
            return "product/productEdit";
        }

        //上传图片
        //图片原始名称
        String originalFilename = product_pic.getOriginalFilename();
        if (product_pic != null && originalFilename!=null && originalFilename.length()>0){
            //存储图片的物理路径
            String pic_path = "/Volumes/MacData/WorkSpaces/upload/images/";
            //生成新的图片名称
            String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
            //新图片
            File newFile = new File(pic_path + newFileName);
            //将内存中的数据写入磁盘
            product_pic.transferTo(newFile);
            //将新图片写到productAndUser中
            productAndUser.setPic(newFileName);

        }

        productService.update(productAndUser);
        return "redirect:findAllProducts.action";
    }

//    批量删除商品信息
    @RequestMapping(value = "/deleteProducts")
    public String deleteProducts(Integer[] items_id)throws Exception{
        //调用service批量删除商品
        System.out.println(items_id);
        return "redirect:findAllProducts.action";
    }

//    获取批量修改的商品信息List类型实现
    @RequestMapping(value = "/productListEdit")
    public String productListEdit(Model model)throws Exception{
        ProductAndUserVo productAndUserVo = new ProductAndUserVo();
        ProductAndUser product = new ProductAndUser();
        product.setName("");
        productAndUserVo.setProductAndUser(product);
        List<ProductAndUser> lists = productService.findProductAndUser(productAndUserVo);
        model.addAttribute("lists",lists);
        return "product/productListEdit";
    }

//    批量修改商品信息提交List类型实现
    @RequestMapping(value = "/productListEditSubmit")
    public String productListEditSubmit(ProductAndUserVo productAndUserVo)throws Exception{
        //调用service批量修改商品
        return "redirect:productListEdit.action";
    }

//    获取批量修改的商品信息Map类型实现
    @RequestMapping(value = "/productMapEdit")
    public String productMapEdit(Model model)throws Exception{
        ProductAndUserVo productAndUserVo = new ProductAndUserVo();
        ProductAndUser product = new ProductAndUser();
        product.setName("");
        productAndUserVo.setProductAndUser(product);
        List<ProductAndUser> lists = productService.findProductAndUser(productAndUserVo);
        model.addAttribute("lists",lists);
        return "product/productMapEdit";
    }


//    批量修改商品信息提交Map类型实现
    @RequestMapping(value = "/productMapEditSubmit")
    public String productMapEditSubmit(ProductAndUserVo productAndUserVo)throws Exception{
        //调用service批量修改商品
        return "redirect:productListEdit.action";
    }

}
